home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-10-16 | 13.4 KB | 613 lines | [TEXT/MPS ] |
- // UAppleObject.cp
- // by Eric Berdahl
- // AppleLink: BERDAHL
- // Interget: eric_berdahl@taligent.com
- // May XX, 1992
- //
- // Copyright © 1992 Eric M. Berdahl
- // All rights reserved.
- //
- // LICENSE
- //
- // UAppleObject is provided under the ego-ware™ system. If you send me a note
- // telling me how cool you think it UAppleObject is, you may incorporate it into
- // any product you like (six-packs of good beer are also acceptable, no C.O.D.
- // shipments, please). Also, you must keep all copyright and other notices in
- // the source code, especially MY NAME (The system is called ego-ware™. Get it?).
-
-
- #ifndef __AEOBJECTS__
- #include <AEObjects.h>
- #endif
-
- #ifndef __EXCEPTIONS__
- #include "Exceptions.h"
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef _UAPPLEOBJECT_
- #include "UAppleObject.h"
- #endif
-
- #ifndef __UMAFAILURE__
- #include "UMAFailure.h"
- #endif
-
-
- // This unit requires a definition for DEBUG (indicating whether or not you
- // want debugging code compiled in). If you don’t set the flag, I’ll just
- // assume you don’t want any.
- #ifndef DEBUG
- #define DEBUG 0
- #endif
-
- //--------------------------------------------------------------------------------
- // TAppleObjectDispatcher
- //--------------------------------------------------------------------------------
-
- TAppleObjectDispatcher* TAppleObjectDispatcher::fgDispatcher = nil;
- Boolean TAppleObjectDispatcher::fgInited = false;
-
-
- TAppleObjectDispatcher::TAppleObjectDispatcher()
- {
- fDisposalList = nil;
- fDisposalListSize = 0;
- fApplication = nil;
- }
-
-
- TAppleObjectDispatcher::~TAppleObjectDispatcher()
- {
- if (fDisposalList != nil)
- DisposeHandle((Handle) fDisposalList);
- }
-
- struct MAEventTableRec
- {
- OSType theClass;
- OSType theID;
- long theValue;
- };
- typedef MAEventTableRec* MAEventTablePointer;
-
- void TAppleObjectDispatcher::Install()
- {
- if (fgDispatcher != nil)
- FailOSErr(errAppleObjectDispatcherAlreadyInstalled);
-
- TRY
- {
- if (!fgInited)
- {
- AEObjectInit();
- fgInited = true;
- }
-
- fgDispatcher = this;
-
- // Install AppleEvent handlers from all aedt resources
- // Look for all AppleEvent dispatch tables…
- short numberOfTables = Count1Resources('aedt');
- FailResError();
-
- for (short tableIndex = 1; tableIndex <= numberOfTables; ++tableIndex)
- {
- Handle tableHandle = Get1IndResource('aedt', tableIndex);
- TRY
- {
- FailResError();
-
- SignedByte savedState = HGetState(tableHandle);
- HLockHi(tableHandle);
-
- long tableSize = GetHandleSize(tableHandle);
- FailMemError();
-
- short tableElements = (short)(tableSize / sizeof(MAEventTableRec));
-
- MAEventTablePointer tablePtr = (MAEventTablePointer) *tableHandle;
-
- // Install a single event handler for all events
- for (short eventIndex = 1; eventIndex <= tableElements; ++eventIndex, ++tablePtr)
- this->InstallAppleEventHandler(tablePtr->theClass, tablePtr->theID, tablePtr->theValue);
-
- HSetState(tableHandle, savedState);
- }
- RECOVER
- {
- if (tableHandle)
- ReleaseResource(tableHandle);
- }
- ENDTRY
-
- ReleaseResource(tableHandle);
- }
-
-
-
-
- // Install a universal object accessor
- FailOSErr(AEInstallObjectAccessor(typeWildCard, typeWildCard,
- TAppleObjectDispatcher::OSLObjectAccessorHandler,
- 0, false));
-
- // Set up the object support library callbacks
- FailOSErr(AESetObjectCallbacks(
- TAppleObjectDispatcher::OSLCompareObjectsHandler,
- TAppleObjectDispatcher::OSLCountObjectsHandler,
- TAppleObjectDispatcher::OSLDisposeTokenHandler,
- nil, nil, nil, nil));
- }
- RECOVER
- {
- fgDispatcher = nil;
- }
- ENDTRY
- }
-
-
- MAppleObject* TAppleObjectDispatcher::ExtractObject(const AEDesc& descriptor)
- {
- MAppleObject* result;
-
- if (descriptor.descriptorType == typeNull)
- result = MAppleObject::GetDefaultAppleObject();
- else
- result = (MAppleObject*)descriptor.dataHandle;
-
- #if DEBUG
- if (descriptor.descriptorType != result->GetAppleClass())
- DebugStr((ConstStr255Param) "Protocol error: object isn’t what it says it is");
- #endif
-
- return result;
- }
-
-
- MAppleObject* TAppleObjectDispatcher::GetTarget(const AppleEvent& message)
- {
- // The target defaults to the application
- MAppleObject* result = MAppleObject::GetDefaultAppleObject();
-
- TRY
- {
- AEDesc theDirectParameter;
- FailOSErr(AEGetParamDesc(&message, keyDirectObject, typeWildCard, &theDirectParameter));
- TRY
- {
- // If the direct object is an object specifier, resolve it into
- // an application domain object.
- if (theDirectParameter.descriptorType == typeObjectSpecifier)
- result = this->ResolveSpecifier(theDirectParameter);
- }
- RECOVER
- {
- OSErr ignoreErr = AEDisposeDesc(&theDirectParameter);
- }
- ENDTRY
- }
- RECOVER
- {
- // It’s all right for there to be no direct object. In that
- // case, we stick with the default.
- if (gFailError == errAEDescNotFound)
- goto NoDescriptor;
- }
- ENDTRY
-
- NoDescriptor:
- FailNIL(result);
-
- return result;
- }
-
-
- void TAppleObjectDispatcher::StuffDescriptor(AEDesc& descriptor,
- MAppleObject* object)
- {
- descriptor.descriptorType = object->GetAppleClass();
- descriptor.dataHandle = (Handle) object;
- }
-
-
- void TAppleObjectDispatcher::HandleAppleEvent(const AppleEvent& message,
- AppleEvent& reply,
- long refCon)
- {
- MAppleObject* theTarget = this->GetTarget(message);
- theTarget->DoAppleEvent(message, reply, refCon);
-
- // Dispose of the token object
- AEDesc fakeToken;
- this->StuffDescriptor(fakeToken, theTarget);
- FailOSErr(AEDisposeToken(&fakeToken));
- }
-
-
- void TAppleObjectDispatcher::AccessContainedObjects(DescType desiredClass,
- const AEDesc& container,
- DescType containerClass,
- DescType form,
- const AEDesc& selectionData,
- AEDesc& value,
- long /* refCon */)
- {
- MAppleObject* containerObject = this->ExtractObject(container);
-
- #if DEBUG
- if (containerObject->GetAppleClass() != containerClass)
- DebugStr((ConstStr255Param) "Protocol error: object isn’t what the AE Manager thinks it is");
- #endif
-
- Boolean needsDisposal;
- MAppleObject* resultObject = containerObject->GetContainedObject(desiredClass,
- form, selectionData,
- needsDisposal);
- if (resultObject == nil)
- FailOSErr(errAENoSuchObject);
-
- this->StuffDescriptor(value, resultObject);
-
- if (needsDisposal)
- this->SetTokenObjectDisposal(resultObject, true);
- }
-
-
- long TAppleObjectDispatcher::CountObjects(const AEDesc& containerToken,
- DescType countObjectsOfType)
- {
- MAppleObject* containerObject = this->ExtractObject(containerToken);
- return containerObject->CountContainedObjects(countObjectsOfType);
- }
-
- Boolean TAppleObjectDispatcher::CompareObjects(DescType operation,
- const AEDesc& obj1,
- const AEDesc& obj2)
- {
- MAppleObject* mObj1 = this->ExtractObject(obj1);
- MAppleObject* mObj2 = this->ExtractObject(obj2);
-
- return mObj1->CompareAppleObjects(operation, *mObj2);
- }
-
- void TAppleObjectDispatcher::DisposeToken(AEDesc& unneededToken)
- {
- MAppleObject* theObject = this->ExtractObject(unneededToken);
- if (this->GetTokenObjectDisposal(theObject))
- delete theObject;
- }
-
-
- Boolean TAppleObjectDispatcher::GetTokenObjectDisposal(const MAppleObject* theObject)
- {
- Boolean result = false;
-
- // Search the list of objects to be disposed. Return true if the object is
- // in the list.
- MAppleObject** curObj = *fDisposalList;
- for (long i = 0; i < fDisposalListSize; i++, curObj++)
- {
- if (theObject == *curObj)
- {
- result = true;
- break;
- }
- }
-
- return result;
- }
-
-
- void TAppleObjectDispatcher::SetTokenObjectDisposal(MAppleObject* theObject,
- Boolean needsDisposal)
- {
- // Search the list of objects to be disposed to see if it currently exists.
- Boolean nilFound = false;
- Boolean found = false;
- MAppleObject** curObj = *fDisposalList;
- for (long i = 0; i < fDisposalListSize; i++, curObj++)
- {
- if (theObject == *curObj)
- {
- found = true;
-
- if (!needsDisposal)
- // remove it from the disposal list
- *curObj = nil;
-
- break;
- }
- else if (*curObj == nil)
- nilFound = true;
- }
-
- if (!found && needsDisposal)
- {
- // it needs to be added to the list
-
- if (nilFound)
- {
- // we can sneak into a nil spot
- curObj = *fDisposalList;
- for (i = 0; i < fDisposalListSize; i++, curObj++)
- {
- if (*curObj == nil)
- {
- *curObj = theObject;
- break;
- }
- }
- }
- else
- {
- // If the list hasn’t been created yet, create a zero-sized list
- if (fDisposalList == nil)
- {
- fDisposalList = (MAppleObject***) NewHandle(0);
- FailNIL(fDisposalList);
- }
-
- TRY
- {
- fDisposalListSize++;
- SetHandleSize((Handle) fDisposalList, fDisposalListSize*sizeof(MAppleObject*));
- FailMemError();
- curObj = *fDisposalList;
- curObj += fDisposalListSize - 1;
- *curObj = theObject;
- }
- RECOVER
- {
- fDisposalListSize--;
- }
- ENDTRY
- }
- }
- }
-
-
- MAppleObject* TAppleObjectDispatcher::ResolveSpecifier(AEDesc& objectSpecifier)
- {
- AEDesc tokenDesc;
- FailOSErr(AEResolve(&objectSpecifier, kAEIDoMinimum, &tokenDesc));
- MAppleObject* result = this->ExtractObject(tokenDesc);
- return result;
- }
-
-
- pascal OSErr TAppleObjectDispatcher::AppleEventHandler(const AppleEvent* message,
- AppleEvent* reply,
- long refCon)
- {
- OSErr result = noErr;
-
- TRY
- {
- GetDispatcher()->HandleAppleEvent(*message, *reply, refCon);
- }
- RECOVER
- {
- result = gFailError;
- goto ReturnErrorCode;
- }
- ENDTRY
-
- ReturnErrorCode:
- return result;
- }
-
- pascal OSErr TAppleObjectDispatcher::OSLObjectAccessorHandler(DescType desiredClass,
- const AEDesc* container,
- DescType containerClass,
- DescType form,
- const AEDesc* selectionData,
- AEDesc* value,
- long refCon)
- {
- OSErr result = noErr;
-
- TRY
- {
- GetDispatcher()->AccessContainedObjects(desiredClass, *container,
- containerClass, form,
- *selectionData,
- *value, refCon);
- }
- RECOVER
- {
- result = gFailError;
- goto ReturnErrorCode;
- }
- ENDTRY
-
- ReturnErrorCode:
- return result;
- }
-
- pascal OSErr TAppleObjectDispatcher::OSLCountObjectsHandler(DescType countObjectsOfType,
- DescType /* containerClass */,
- const AEDesc* containerToken,
- long* result)
- {
- OSErr theErr = noErr;
-
- TRY
- {
- *result = GetDispatcher()->CountObjects(*containerToken, countObjectsOfType);
- }
- RECOVER
- {
- theErr = gFailError;
- goto ReturnErrorCode;
- }
- ENDTRY
-
- ReturnErrorCode:
- return theErr;
- }
-
-
- pascal OSErr TAppleObjectDispatcher::OSLCompareObjectsHandler(DescType operation,
- const AEDesc *obj1,
- const AEDesc *obj2,
- Boolean *answer)
- {
- OSErr result = noErr;
-
- TRY
- {
- *answer = GetDispatcher()->CompareObjects(operation, *obj1, *obj2);
- }
- RECOVER
- {
- result = gFailError;
- goto ReturnErrorCode;
- }
- ENDTRY
-
- ReturnErrorCode:
- return result;
- }
-
-
- pascal OSErr TAppleObjectDispatcher::OSLDisposeTokenHandler(AEDesc* unneededToken)
- {
- OSErr result = noErr;
-
- TRY
- {
- GetDispatcher()->DisposeToken(*unneededToken);
- }
- RECOVER
- {
- result = gFailError;
- goto ReturnErrorCode;
- }
- ENDTRY
-
- ReturnErrorCode:
- return result;
- }
-
-
- void TAppleObjectDispatcher::InstallAppleEventHandler(AEEventClass theClass,
- AEEventID theID,
- long refCon)
- {
- FailOSErr(AEInstallEventHandler(theClass, theID,
- (EventHandlerProcPtr) TAppleObjectDispatcher::AppleEventHandler,
- refCon, false));
- }
-
-
- //--------------------------------------------------------------------------------
- // MAppleObject
- //--------------------------------------------------------------------------------
-
- Boolean MAppleObject::fgInited = false;
- MAppleObject* MAppleObject::fgDefaultAppleObject = nil;
-
-
- MAppleObject::MAppleObject()
- {
- }
-
-
- MAppleObject::MAppleObject(const MAppleObject& /* copy */)
- {
- }
-
-
- MAppleObject::~MAppleObject()
- {
- if (MAppleObject::GetDefaultAppleObject() == this)
- MAppleObject::SetDefaultAppleObject(nil);
-
- TAppleObjectDispatcher::GetDispatcher()->SetTokenObjectDisposal(this, false);
- }
-
-
- MAppleObject& MAppleObject::operator=(const MAppleObject& /* assignTo */)
- {
- return *this;
- }
-
-
- void MAppleObject::InitAppleObject(TAppleObjectDispatcher* dispatcher)
- {
- // create a dispatcher if one wasn't passed in
- if (dispatcher == nil)
- {
- dispatcher = new TAppleObjectDispatcher();
- FailNIL(dispatcher);
- }
-
- // Install the dispatcher
- dispatcher->Install();
-
- fgInited = true;
- }
-
-
- long MAppleObject::CountContainedObjects(DescType /* ofType */)
- {
- return 0;
- }
-
-
- Boolean MAppleObject::CompareAppleObjects(DescType /* operation */,
- const MAppleObject& /* toWhat */)
- {
- return false;
- }
-
-
- void MAppleObject::DoAppleEvent(const AppleEvent& /* message */,
- AppleEvent& /* reply */, long /* refCon */)
- {
- FailOSErr(errAEEventNotHandled);
- }
-
-
- MAppleObject* MAppleObject::GetContainedObject(DescType /* desiredType */,
- DescType /* keyForm */,
- const AEDesc& /* keyData */,
- Boolean& /* needDisposal */)
- {
- return nil;
- }
-
-
- void MAppleObject::GotRequiredParameters(const AppleEvent& theAppleEvent)
- {
- // look for the keyMissedKeywordAttr, just to see if it's there
- DescType returnedType;
- Size actualSize;
- OSErr theErr = AEGetAttributePtr(&theAppleEvent, keyMissedKeywordAttr,
- typeWildCard, &returnedType, nil, 0,
- &actualSize);
-
- if (theErr == noErr)
- {
- // Since the attribute exists, we missed a parameter somewhere.
- FailOSErr(errAEParamMissed);
- }
- else if (theErr != errAEDescNotFound)
- {
- // The only error that is OK is to say that the descriptor was not
- // found (indicating that we got all the parameters). If any other
- // error occurred, throw it.
- FailOSErr(theErr);
- }
- }
-
-
- void MAppleObject::SetDefaultAppleObject(MAppleObject* defaultObject)
- {
- fgDefaultAppleObject = defaultObject;
- }
-